package com.ruoyix.im.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyix.common.core.domain.R;
import com.ruoyix.common.core.domain.entity.SysUser;
import com.ruoyix.common.core.page.TableDataInfo;
import com.ruoyix.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyix.common.helper.LoginHelper;
import com.ruoyix.im.domain.ImChatUserFriend;
import com.ruoyix.im.domain.bo.ImChatUserFriendBo;
import com.ruoyix.im.domain.vo.ImChatUserFriendVo;
import com.ruoyix.im.domain.vo.UserFriendVO;
import com.ruoyix.im.mapper.ImChatUserFriendMapper;
import com.ruoyix.im.service.IImChatUserFriendService;
import com.ruoyix.im.websocket.ImConfigConst;
import com.ruoyix.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 好友Service业务层处理
 *
 * @author ruoyi
 * @date 2024-05-27
 */
@RequiredArgsConstructor
@Service
public class ImChatUserFriendServiceImpl  extends ServiceImpl<ImChatUserFriendMapper, ImChatUserFriend> implements IImChatUserFriendService {

    private final ImChatUserFriendMapper baseMapper;
    private final SysUserMapper sysUserMapper;
    /**
     * 查询好友
     */
    @Override
    public ImChatUserFriendVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询好友列表
     */
    @Override
    public TableDataInfo<ImChatUserFriendVo> queryPageList(ImChatUserFriendBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ImChatUserFriend> lqw = buildQueryWrapper(bo);
        Page<ImChatUserFriendVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询好友列表
     */
    @Override
    public List<ImChatUserFriendVo> queryList(ImChatUserFriendBo bo) {
        LambdaQueryWrapper<ImChatUserFriend> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ImChatUserFriend> buildQueryWrapper(ImChatUserFriendBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ImChatUserFriend> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getUserId() != null, ImChatUserFriend::getUserId, bo.getUserId());
        lqw.eq(bo.getFriendId() != null, ImChatUserFriend::getFriendId, bo.getFriendId());
        lqw.eq(bo.getFriendStatus() != null, ImChatUserFriend::getFriendStatus, bo.getFriendStatus());
        return lqw;
    }

    /**
     * 新增好友
     */
    @Override
    public Boolean insertByBo(ImChatUserFriendBo bo) {
        ImChatUserFriend add = BeanUtil.toBean(bo, ImChatUserFriend.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改好友
     */
    @Override
    public Boolean updateByBo(ImChatUserFriendBo bo) {
        ImChatUserFriend update = BeanUtil.toBean(bo, ImChatUserFriend.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ImChatUserFriend entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除好友
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }


    public R<Void> addFriend(Long friendId, String remark) {
        SysUser friend = sysUserMapper.selectUserById(friendId);
        if (friend == null) {
            return R.fail("用户不存在！");
        }

        if (StringUtils.isEmpty(remark)) {
            remark = LoginHelper.getUsername();
        }

        Long userId = LoginHelper.getUserId();

        Long count = lambdaQuery()
            .and(wrapper -> wrapper.eq(ImChatUserFriend::getUserId, userId).eq(ImChatUserFriend::getFriendId, friendId))
            .or(wrapper -> wrapper.eq(ImChatUserFriend::getFriendId, userId).eq(ImChatUserFriend::getUserId, friendId))
            .count();
        if (count > 0) {
            return R.ok();
        }

        ImChatUserFriend imChatFriend = new ImChatUserFriend();
        imChatFriend.setUserId(friendId);
        imChatFriend.setFriendId(userId);
        imChatFriend.setFriendStatus(ImConfigConst.FRIEND_STATUS_NOT_VERIFY);
        imChatFriend.setRemark(remark);
        save(imChatFriend);
        return R.ok();
    }


    public List<UserFriendVO> getUserFriendVOS(Long friendStatus) {
        Long userId = LoginHelper.getUserId();
        LambdaQueryChainWrapper<ImChatUserFriend> wrapper = lambdaQuery().eq(ImChatUserFriend::getUserId, userId);
        if (friendStatus != null) {
            wrapper.eq(ImChatUserFriend::getFriendStatus, friendStatus);
        }

        List<ImChatUserFriend> userFriends = wrapper.orderByDesc(ImChatUserFriend::getCreateTime).list();
        List<UserFriendVO> userFriendVOS = new ArrayList<>(userFriends.size());
        userFriends.forEach(userFriend -> {
            SysUser friend = sysUserMapper.selectUserById(userFriend.getFriendId());
            if (friend != null) {
                UserFriendVO userFriendVO = new UserFriendVO();
                userFriendVO.setId(userFriend.getId());
                userFriendVO.setUserId(userFriend.getUserId());
                userFriendVO.setFriendId(userFriend.getFriendId());
                userFriendVO.setCreateTime(userFriend.getCreateTime());
                userFriendVO.setRemark(StringUtils.hasText(userFriend.getRemark()) ? userFriend.getRemark() : friend.getUserName());
                userFriendVO.setFriendStatus(userFriend.getFriendStatus());
                userFriendVO.setUsername(friend.getUserName());
                userFriendVO.setAvatar(friend.getAvatar());
                userFriendVO.setGender(Integer.valueOf(friend.getSex()));
                userFriendVO.setIntroduction("friend.getIntroduction()");
                userFriendVOS.add(userFriendVO);
            }
        });
        return userFriendVOS;
    }


    public R<Void> changeFriend(Long friendId, Long friendStatus, String remark) {
        Long userId = LoginHelper.getUserId();
        ImChatUserFriend userFriend = lambdaQuery()
            .eq(ImChatUserFriend::getUserId, userId)
            .eq(ImChatUserFriend::getFriendId, friendId).one();

        if (userFriend == null) {
            return R.fail("好友不存在！");
        }

        if (friendStatus != null) {
            if (friendStatus.equals(ImConfigConst.FRIEND_STATUS_PASS)) {
                lambdaUpdate()
                    .set(ImChatUserFriend::getFriendStatus, friendStatus)
                    .eq(ImChatUserFriend::getId, userFriend.getId()).update();

                ImChatUserFriend imChatFriend = new ImChatUserFriend();
                imChatFriend.setUserId(friendId);
                imChatFriend.setFriendId(userId);
                imChatFriend.setRemark(LoginHelper.getUsername());
                imChatFriend.setFriendStatus(ImConfigConst.FRIEND_STATUS_PASS);
                save(imChatFriend);
            }

            if (friendStatus.equals(ImConfigConst.FRIEND_STATUS_BAN)) {
                removeById(userFriend.getId());
                lambdaUpdate()
                    .eq(ImChatUserFriend::getUserId, friendId)
                    .eq(ImChatUserFriend::getFriendId, userId).remove();
            }
        }

        if (StringUtils.hasText(remark)) {
            lambdaUpdate()
                .set(ImChatUserFriend::getRemark, remark)
                .eq(ImChatUserFriend::getId, userFriend.getId()).update();
        }


        return R.ok();
    }

    @Override
    public TableDataInfo<ImChatUserFriendVo> selectFriendsList(Long userId) {
        List<ImChatUserFriendVo> result = baseMapper.selectFriendsList(userId);
        return TableDataInfo.build(result);
    }
}
